package com.superhelper.task.job.order;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.sankuai.sjst.platform.developer.domain.RequestDomain;
import com.sankuai.sjst.platform.developer.domain.RequestMethod;
import com.sankuai.sjst.platform.developer.domain.RequestSysParams;
import com.sankuai.sjst.platform.developer.request.CipCaterStringPairRequest;
import com.sankuai.sjst.platform.developer.request.CipCaterTakeoutOrderQueryByIdRequest;
import com.superhelper.common.domain.AuserShop;
import com.superhelper.common.domain.PushMsgType;
import com.superhelper.common.domain.ele.AccessToken;
import com.superhelper.common.domain.mt.MtOrderPushEntity;
import com.superhelper.common.service.AliMQProducerService;
import com.superhelper.common.utils.JsonHelper;
import com.superhelper.task.job.ShopCache;

import eleme.openapi.sdk.oauth.response.Token;

public class MtUnPushOrderJob implements SimpleJob {
    private static final Logger log = LoggerFactory.getLogger(MtUnPushOrderJob.class);
    @Autowired
    private AliMQProducerService producer;

    @Value("${mt.sign.key}")
    private String signKey = "lj0ev7ovcjl1nq1p";

    @Autowired
    private ShopCache shopCache;

    private ExecutorService es = Executors.newFixedThreadPool(5);
    private ExecutorService futureEs = Executors.newFixedThreadPool(5);

    @Override
    public void execute(ShardingContext shardingContext) {
        log.info("start...");
        final List<Future<Integer>> futures = new ArrayList<>();
        for (final AuserShop shop : shopCache.getAllShop()) {
            if (!"mt".equals(shop.getShop_type())) {
                continue;
            }
            ThreadPoolExecutor ep = (ThreadPoolExecutor) es;
            // log.info("task es:{}", ep);
            Future<Integer> future = es.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    AccessToken accessToken = JsonHelper.fromJson(shop.getToken(), AccessToken.class);
                    final Token token = new Token();
                    token.setAccessToken(accessToken.getToken());
                    token.setExpires(accessToken.getExpires());
                    token.setRefreshToken(accessToken.getRefreshToken());
                    token.setTokenType(accessToken.getTokenType());

                    try {

                        List<Map<String, Object>> list = queryByEpoids(shop.getShopId(), token.getAccessToken());
                        log.info("shopId:{}, unPushSize:{}", shop.getShopId(), list == null ? 0 : list.size());
                        if (list != null) {
                            for (Map<String, Object> map : list) {
                                String orderId = map.get("orderId") + "";
                                String ePoiId = map.get("epoiId") + "";
                                String orderStr = queryByid(shop.getShopId(), token.getAccessToken(), orderId);
                                if (StringUtils.isNotBlank(orderStr)) {
                                    log.info("mt->unPushSize orderId:{}", orderId);
                                    MtOrderPushEntity mt = new MtOrderPushEntity();
                                    mt.setePoiId(ePoiId);
                                    mt.setOrder(orderStr);
                                    mt.setPushType(PushMsgType.ORDER_CREATED.getValue());
                                    producer.sendMtOrder(Long.parseLong(orderId), PushMsgType.ORDER_CREATED.getValue(),
                                            mt);
                                }
                            }
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return 0;
                }
            });
            futures.add(future);
        }
        ThreadPoolExecutor ep2 = (ThreadPoolExecutor) futureEs;
        // log.info("futureEs es:{}", ep2);
        futureEs.execute(new Runnable() {
            @Override
            public void run() {
                for (Future<Integer> future : futures) {
                    try {
                        future.get(100, TimeUnit.MILLISECONDS);
                    } catch (Exception e) {
                        future.cancel(true);
                    }
                }
            }
        });
        log.info("end...");
    }

    public List<Map<String, Object>> queryByEpoids(String shopId, String token) throws Exception {
        long time = System.currentTimeMillis();
        CipCaterTakeoutOrderQueryByEpoisRequest request = new CipCaterTakeoutOrderQueryByEpoisRequest();
        request.setRequestSysParams(getSysParams(shopId, token));
        request.setEpoiIds(shopId);
        String body = request.doRequest();
        // log.info("[mt->queryByEpoids]response,{},{}", request.getUrl(),
        // body);
        log.info("cost:{}", System.currentTimeMillis() - time);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);
        if (map.containsKey("data")) {
            return (List) map.get("data");
        }
        return null;
    }

    private RequestSysParams getSysParams(String shopId, String appAuthToken) {
        RequestSysParams sysParams = new RequestSysParams();
        sysParams.setAppAuthToken(appAuthToken);
        sysParams.setCharset("utf-8");
        sysParams.setSecret(signKey);
        return sysParams;
    }

    public String queryByid(String shopId, String token, String orderId) throws Exception {

        CipCaterTakeoutOrderQueryByIdRequest request = new CipCaterTakeoutOrderQueryByIdRequest();
        request.setRequestSysParams(getSysParams(shopId, token));
        request.setOrderId(Long.parseLong(orderId));
        String body = request.doRequest();
        log.info("[mt->queryByid]response,{},{}", request.getUrl(), body);
        Map<String, Object> map = JsonHelper.fromJson(body, Map.class);

        if (map.containsKey("data")) {
            Map result = (Map) map.get("data");
            return JsonHelper.toJson(map);
        }
        return null;
    }

    class CipCaterTakeoutOrderQueryByEpoisRequest extends CipCaterStringPairRequest {

        private String epoiIds;

        public CipCaterTakeoutOrderQueryByEpoisRequest() {
            this.url = RequestDomain.preUrl.getValue() + "/waimai/order/queryByEpoids";
            this.requestMethod = RequestMethod.POST;
        }

        @Override
        public Map<String, String> getParams() {
            return new HashMap<String, String>() {
                {
                    put("epoiIds", epoiIds);
                }
            };
        }

        @Override
        public boolean paramsAbsent() {
            return epoiIds == null;
        }

        public String getEpoiIds() {
            return epoiIds;
        }

        public void setEpoiIds(String epoiIds) {
            this.epoiIds = epoiIds;
        }

    }

    public static void main(String args[]) {
        MtUnPushOrderJob job = new MtUnPushOrderJob();
        try {
            // job.queryByEpoids("1506246144803739",
            // "f850fec99223c7687da2d770f7455f53dc79fcc8a978cc0107d923cd5de3dc903b0b222fa11e2a6149b42584f8394fee");

            job.queryByid("1506246144803739",
                    "f850fec99223c7687da2d770f7455f53dc79fcc8a978cc0107d923cd5de3dc903b0b222fa11e2a6149b42584f8394fee",
                    "6308172823");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
